import java.util.PriorityQueue;
import java.util.TreeMap;
import java.util.TreeSet;

// 名为Code02_TreeSetAndTreeMap的类
public class Code02_TreeSetAndTreeMap {
    public static void main(String[] args) {
        // 创建一个TreeMap，其底层是红黑树结构，键为Integer类型，值为String类型
        TreeMap<Integer, String> treeMap = new TreeMap<>();

        // 向TreeMap中添加键值对，键为数字，值为对应的描述字符串
        treeMap.put(5, "这是5");
        treeMap.put(7, "这是7");
        treeMap.put(1, "这是1");
        treeMap.put(2, "这是2");
        treeMap.put(3, "这是3");
        treeMap.put(4, "这是4");
        treeMap.put(8, "这是8");

        // 检查TreeMap是否包含键为1的键值对，输出结果为true或false
        System.out.println(treeMap.containsKey(1));
        // 检查TreeMap是否包含键为10的键值对，输出结果为true或false
        System.out.println(treeMap.containsKey(10));
        // 获取键为4对应的字符串值并输出
        System.out.println(treeMap.get(4));
        // 将键为4的值更新为"张三是4"
        treeMap.put(4, "张三是4");
        // 再次获取键为4对应的字符串值并输出，此时应为"张三是4"
        System.out.println(treeMap.get(4));
        // 从TreeMap中移除键为4的键值对
        treeMap.remove(4);
        // 检查获取键为4的值是否为null，由于已移除，结果应为true
        System.out.println(treeMap.get(4) == null);

        // 获取TreeMap中的最小键并输出
        System.out.println(treeMap.firstKey());
        // 获取TreeMap中的最大键并输出
        System.out.println(treeMap.lastKey());
        // 获取TreeMap中所有键小于等于4的键中最大的那个键并输出
        System.out.println(treeMap.floorKey(4));
        // 获取TreeMap中所有键大于等于4的键中最小的那个键并输出
        System.out.println(treeMap.ceilingKey(4));

        System.out.println("========");

        // 创建一个TreeSet，其底层是红黑树结构，元素为Integer类型
        TreeSet<Integer> set = new TreeSet<>();
        // 向TreeSet中添加元素，TreeSet会自动去重，这里添加了3和4，但实际只会各保存一个
        set.add(3);
        set.add(3);
        set.add(4);
        set.add(4);
        // 输出TreeSet的大小，应为2
        System.out.println("有序表大小 : " + set.size());
        // 循环取出TreeSet中的最小元素（通过pollFirst方法）并输出，直到TreeSet为空
        while (!set.isEmpty()) {
            System.out.println(set.pollFirst());
            // 如果使用pollLast则是取出最大元素
        }

        System.out.println("========");

        // 创建一个PriorityQueue（默认是小根堆），元素为Integer类型
        PriorityQueue<Integer> heap1 = new PriorityQueue<>();
        // 向小根堆中添加元素，小根堆会根据元素大小自动调整堆结构
        heap1.add(3);
        heap1.add(3);
        heap1.add(4);
        heap1.add(4);
        // 输出小根堆的大小，应为4
        System.out.println("堆大小 : " + heap1.size());
        // 循环取出小根堆的堆顶元素（最小元素）并输出，直到小根堆为空
        while (!heap1.isEmpty()) {
            System.out.println(heap1.poll());
        }

        System.out.println("========");

        // 创建一个定制的PriorityQueue（大根堆），通过传入比较器来实现
        // 比较器的逻辑是(b - a)，使得元素按照从大到小的顺序排列在堆中
        PriorityQueue<Integer> heap2 = new PriorityQueue<>((a, b) -> b - a);
        // 向大根堆中添加元素，大根堆会根据自定义的比较器调整堆结构
        heap2.add(3);
        heap2.add(3);
        heap2.add(4);
        heap2.add(4);
        // 输出大根堆的大小，应为4
        System.out.println("堆大小 : " + heap2.size());
        // 循环取出大根堆的堆顶元素（最大元素）并输出，直到大根堆为空
        while (!heap2.isEmpty()) {
            System.out.println(heap2.poll());
        }
    }
}